1 module cgi.router; 2 /***************************************************************************** 3 * package: cgi 4 * module cgi.router 5 * File: router.d 6 * Description: utility d module that allows conditional execution of classes that implement the ROUTE interface by 7 * matching a string to the CGI PATH_INFO or QUERY_STRING. 8 * Author: Joseph M. Rice (ricejm01@gmail.com) 9 * Date: Thu Nov 13 13:59:10 EST 2015 10 * 11 *MIT License 12 * 13 *Copyright (c) 2014-2016 Joseph M. Rice <ricejm01@gmail.com> 14 * 15 *Permission is hereby granted, free of charge, to any person obtaining a copy 16 *of this software and associated documentation files (the "Software"), to deal 17 *in the Software without restriction, including without limitation the rights 18 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 *copies of the Software, and to permit persons to whom the Software is 20 *furnished to do so, subject to the following conditions: 21 * 22 *The above copyright notice and this permission notice shall be included in all 23 *copies or substantial portions of the Software. 24 * 25 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 *SOFTWARE. 32 ***************************************************************************/ 33 34 import cgi.cgi; 35 import std.algorithm; 36 37 class RouterException : Exception 38 { 39 this(string msg, string file = __FILE__, ulong line = cast(ulong)__LINE__, Throwable next = null) 40 { 41 super(msg,file,line,next); 42 } 43 } 44 45 /** 46 * interface ROUTE 47 * 48 * interface class that allows you to create classes to be used 49 * with the ROUTER class. 50 */ 51 interface ROUTE 52 { 53 /** 54 * main method that will perform the actions/purpose of your class. 55 * 56 */ 57 void run(CGI cgi); 58 } 59 60 /** 61 * class ROUTER 62 * 63 * Description: handle path_info or CGI query string information to logically 64 * determine a cgi application flow control. This class allows you use develop 65 * a restful api, and then serve up content based upon the path_info or CGI 66 * query string information. IE. "/foo/" or "?func=foo" 67 */ 68 class ROUTER 69 { 70 CGI cgi; 71 private string path; 72 73 this(CGI cgi) { 74 // Constructor code 75 if (!cgi) throw new RouterException("cgi environment is not initialized or is null"); 76 this.cgi = cgi; 77 } 78 79 /** 80 * run a route based off the path_info envirement variable 81 * 82 * returns true if the a cgi.PATH_INFO starts with the path variable 83 */ 84 bool runRoute(string path, ROUTE route) { 85 ulong i = 0; 86 bool pathMatch = false; 87 88 if (!path || path.length == 0) throw new RouterException("Un-initialized or null path"); 89 90 this.path = path; 91 92 if (!route) throw new RouterException("Un-initialized or null route"); 93 94 if (startsWith(cgi.PATH_INFO,path)) pathMatch = true; 95 96 if (pathMatch) route.run(cgi); 97 98 return pathMatch; 99 } 100 101 /** 102 * Run a route based off if a cgi variable exists in a query string. 103 * 104 * returns true if the name variable exists in the cgi query string. 105 */ 106 bool runQueryRoute(string name, ROUTE route) { 107 bool match = false; 108 109 if (!route) throw new RouterException("Un-initialized or null route"); 110 111 if (cgi.exists(name)) { 112 route.run(cgi); 113 match = true; 114 } 115 116 return match; 117 } 118 119 string basePath() { 120 return this.path; 121 } 122 } 123